package administracion.managedBean.usuarios;

import Entities.Chofer;
import Entities.Empleado;
import Entities.Mesa;
import Entities.Mozo;
import Entities.Vehiculo;
import ejb.ConsultaUniversalFacadeLocal;
import ejb.EmpleadoFacadeLocal;
import ejb.UsuarioFacadeLocal;
import ejb.VehiculoFacadeLocal;
import ejb.soportes.Consulta;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
import org.primefaces.model.LazyDataModel;
import sesion.PermisoPagina;
import tablemodel.GeneralLazyModel;
import util.PageCodeGenerico;

@ManagedBean
@ViewScoped
public class PCEmpleado extends PageCodeGenerico implements Serializable {

    @EJB
    private ConsultaUniversalFacadeLocal consultaUniversalFacade;
    @EJB
    private EmpleadoFacadeLocal entidadFacade;
    @EJB
    private VehiculoFacadeLocal vehiculoFacade;
    @EJB
    private UsuarioFacadeLocal usuarioFacade;
    private LazyDataModel<Empleado> listado;
    private Empleado temporal;
    private Mozo mozoTemporal;
    private Chofer choferTemporal;
    private Properties colsVisible;
    private Map<String, String> checksVisible;
    private List<String> selectedChecksVisible;
    private Accion accion = Accion.CREAR;
    private Map<String, Integer> vehiculosSelect = new HashMap<>();
    private Integer vehiculo;
    private Integer rol;
    private String documento;
    private Date fechaNac;
    private String contrasenia;
    private LazyDataModel<Mesa> listaMesas;
    private String nomUsuarioCheck;

    public Integer getVehiculo() {
        return vehiculo;
    }

    public void setVehiculo(Integer vehiculo) {
        this.vehiculo = vehiculo;
    }

    public Map<String, Integer> getVehiculosSelect() {
        return vehiculosSelect;
    }

    public void setVehiculosSelect(Map<String, Integer> vehiculosSelect) {
        this.vehiculosSelect = vehiculosSelect;
    }

    public Integer getRol() {
        return rol;
    }

    public void setRol(Integer rol) {
        this.rol = rol;
    }

    public String getDocumento() {
        return documento;
    }

    public void setDocumento(String documento) {
        this.documento = documento;
    }

    public Date getFechaNac() {
        return fechaNac;
    }

    public void setFechaNac(Date fechaNac) {
        this.fechaNac = fechaNac;
    }

    public String getContrasenia() {
        return contrasenia;
    }

    public void setContrasenia(String contrasenia) {
        this.contrasenia = contrasenia;
    }

    public LazyDataModel<Mesa> getListaMesas() {
        return listaMesas;
    }

    public void setListaMesas(LazyDataModel<Mesa> listaMesas) {
        this.listaMesas = listaMesas;
    }

    public Mozo getMozoTemporal() {
        return mozoTemporal;
    }

    public void setMozoTemporal(Mozo mozoTemporal) {
        this.mozoTemporal = mozoTemporal;
    }

    public Chofer getChoferTemporal() {
        return choferTemporal;
    }

    public void setChoferTemporal(Chofer choferTemporal) {
        this.choferTemporal = choferTemporal;
    }

    public String getNomUsuarioCheck() {
        return nomUsuarioCheck;
    }

    public void setNomUsuarioCheck(String nomUsuarioCheck) {
        this.nomUsuarioCheck = nomUsuarioCheck;
    }

    /**
     * Creates a new instance of InternoBean
     */
    public PCEmpleado() {
        super();
        this.listado = new GeneralLazyModel<>(new Empleado());
        this.temporal = new Empleado();
        this.colsVisible = new Properties();
        this.listaMesas = new GeneralLazyModel<>(new Mesa());
        this.mozoTemporal = new Mozo();
        this.choferTemporal = new Chofer();
    }

    public void cargarVehiculos() {
        try {
            Vehiculo v = new Vehiculo();
            v.setActivo(true);
            List<Vehiculo> listaVehiculos = consultaUniversalFacade.consultar(new Consulta(v));
            for (int i = 0; i < listaVehiculos.size(); i++) {
                vehiculosSelect.put(listaVehiculos.get(i).getDescripcion(), listaVehiculos.get(i).getId());
            }
        } catch (Exception ex) {
            super.setearError(ex);
        }
    }

    public String devolverTituloDlg() {
        switch (this.accion) {
            case CREAR:
                return "Crear";
            case EDITAR:
                return "Editar";
            default:
                return "";
        }
    }

    public PermisoPagina consultarPermisos() {
        if (getMi_sesion() != null) {
            return getMi_sesion().consultarPermisos(Empleado.class);
        } else {
            return new PermisoPagina();
        }
    }

    public String devolverTxtBtnCancelarDlg() {
        switch (this.accion) {
            case VER:
                return "Cerrar";
            default:
                return "Cancelar";
        }
    }

    public String devolverTxtLimpiarFormDlg() {
        switch (this.accion) {
            case EDITAR:
                return "Restablecer formulario";
            default:
                return "Limpiar formulario";
        }
    }

    public boolean esCrear() {
        return this.accion == Accion.CREAR;
    }

    public boolean esEditar() {
        return this.accion == Accion.EDITAR;
    }

    public boolean esVer() {
        return this.accion == Accion.VER;
    }

    @PostConstruct
    public void reinicializarChecks() {
        this.checksVisible = new HashMap<>();
        this.checksVisible.put("Id", "id");
        this.checksVisible.put("Rol", "rol");
        this.checksVisible.put("Puesto", "puestoTrabajo");
        this.checksVisible.put("Usuario", "nombreUsuario");
        this.checksVisible.put("Nombre", "nombre");
        this.checksVisible.put("Apellido", "apellido");
        this.checksVisible.put("Documento", "ci");
        this.checksVisible.put("Correo", "email");
        this.checksVisible.put("Teléfono", "telefono");
        this.checksVisible.put("Celular", "cel");
        this.checksVisible.put("Fecha de Nacimiento", "fechaNac");
        this.checksVisible.put("Departamento", "departamento");
        this.checksVisible.put("Ciudad", "ciudad");
        this.checksVisible.put("Calle", "calle");
        this.checksVisible.put("Numero de puerta", "numero");
        this.checksVisible.put("Detalles", "detalle");

        this.selectedChecksVisible = new ArrayList<>();
        this.selectedChecksVisible.add("id");
        this.selectedChecksVisible.add("rol");
        this.selectedChecksVisible.add("puestoTrabajo");
        this.selectedChecksVisible.add("nombreUsuario");
        this.selectedChecksVisible.add("nombre");
        this.selectedChecksVisible.add("apellido");

        setearVisibles();
    }

    public void setearVisibles() {
        for (Map.Entry<String, String> entry : checksVisible.entrySet()) {
            String valor = entry.getValue();
            boolean existe = false;
            for (Iterator<String> it = selectedChecksVisible.iterator(); it.hasNext();) {
                String colSel = it.next();
                if (colSel.trim().toLowerCase().equals(valor.trim().toLowerCase())) {
                    existe = true;
                    break;
                }
            }
            this.colsVisible.put(valor, existe);
        }
    }

    public LazyDataModel<Empleado> getListado() {
        if (consultarPermisos().isVer()) {
            return listado;
        } else {
            return null;
        }
    }

    public void setListado(LazyDataModel<Empleado> listado) {
        this.listado = listado;
    }

    public Empleado getTemporal() {
        return temporal;
    }

    public void setTemporal(Empleado temporal) {
        this.temporal = temporal;
    }

    public Map<String, String> getChecksVisible() {
        return checksVisible;
    }

    public void setChecksVisible(Map<String, String> checksVisible) {
        this.checksVisible = checksVisible;
    }

    public List<String> getSelectedChecksVisible() {
        return selectedChecksVisible;
    }

    public void setSelectedChecksVisible(List<String> selectedChecksVisible) {
        this.selectedChecksVisible = selectedChecksVisible;
    }

    public void reinicializarTemporal() {
        this.temporal = new Empleado();
        this.accion = Accion.CREAR;
        this.documento = null;
        this.fechaNac = null;
        this.contrasenia = "";
        this.vehiculo = null;
        this.rol = null;
    }

    public void establecerTemporal(Empleado objeto, boolean isEditar) {
        this.temporal = (objeto == null) ? new Empleado() : objeto;
        if (objeto instanceof Mozo) {
            this.mozoTemporal = (Mozo) temporal;
        } else if (objeto instanceof Chofer) {
            this.choferTemporal = (Chofer) temporal;
            this.vehiculo = this.choferTemporal.getVehiculo().getId();
        } else {
            this.temporal = (Empleado) temporal;
        }
        this.accion = (isEditar) ? Accion.EDITAR : Accion.VER;
        this.fechaNac = this.convertirCalendarADate(this.temporal.getFechaNac());
        this.documento = String.valueOf(this.temporal.getCi());
        this.rol = this.temporal.getRol();
        this.nomUsuarioCheck = this.temporal.getNombreUsuario();
        cargarVehiculos();
    }

    public void reinicializarColsVisible() {
        this.colsVisible.clear();
    }

    /**
     *
     * @param col Sin tildes ni espacios y en minúsculas
     * @param visible
     */
    public void establecerColVisible(String col, boolean visible) {
        this.colsVisible.put(col, visible);
    }

    /**
     *
     * @param col Sin tildes ni espacios y en minúsculas
     * @return
     */
    public boolean getColVisible(String col) {
        boolean resp = true;
        if (this.colsVisible.get(col) != null) {
            try {
                resp = (boolean) this.colsVisible.get(col);
            } catch (Exception e) {
            }
        }
        return resp;
    }

    public void eliminar() {
        if (consultarPermisos().isBaja()) {
            if (this.temporal != null) {
                try {
                    entidadFacade.eliminar(this.temporal);
                    setearInfo("Operación finalizada correctamente.");
                } catch (Exception e) {
                    setearError(e);
                }
            } else {
                setearInfo("Nada que eliminar.");
            }
        } else {
            setearError("No tiene permisos suficientes para ejecutar esta acción");
        }
    }

    public boolean guardar(String mi_param) {
        switch (this.accion) {
            case CREAR:
                return crear(mi_param);
            case EDITAR:
                return modificar(mi_param);
            default:
                return false;
        }
    }

    private boolean modificar(String mi_param) {
        if (consultarPermisos().isModificacion()) {
            try {
                if ((this.nomUsuarioCheck.equals(this.temporal.getNombreUsuario())) || (!usuarioFacade.existeUsuario(this.temporal.getNombreUsuario()))) {
                    String codigo = String.valueOf(this.temporal.getId());
                    switch (this.rol) {
                        case 5:
                            Mozo m = (Mozo) this.temporal;
                            m.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            if (!this.contrasenia.equals("")) {
                                m.setContrasenia(this.contrasenia);
                            }
                            m.setRol(this.rol);
                            m.setCi(this.convertirCi(this.documento));
                            entidadFacade.editar(m);
                            break;
                        case 2:
                            Chofer c = (Chofer) this.temporal;
                            c.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            if (!this.contrasenia.equals("")) {
                                c.setContrasenia(this.contrasenia);
                            }
                            c.setRol(this.rol);
                            c.setCi(this.convertirCi(this.documento));
                            Vehiculo v = vehiculoFacade.buscarPorId(this.vehiculo);
                            c.setVehiculo(v);
                            entidadFacade.editar(c);
                            break;
                        default:
                            this.temporal.setRol(this.rol);
                            if (!this.contrasenia.equals("")) {
                                temporal.setContrasenia(this.contrasenia);
                            }
                            this.temporal.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            this.temporal.setCi(this.convertirCi(this.documento));
                            entidadFacade.editar(this.temporal);
                            break;
                    }
                    setearInfo("Modificación exitosa " + "de " + mi_param + " con código: " + codigo);
                    RequestContext.getCurrentInstance().addCallbackParam("correcto", true);
                    RequestContext.getCurrentInstance().addCallbackParam("param", mi_param);
                    return true;
                } else {
                    super.setearAdvertencia("El Nombre de Usuario ya existe en el Sistema");
                    RequestContext.getCurrentInstance().addCallbackParam("correcto", false);
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return false;
        }
    }

    private boolean crear(String mi_param) {
        if (consultarPermisos().isAlta()) {
            try {
                if (!usuarioFacade.existeUsuario(this.temporal.getNombreUsuario())) {
                    switch (this.rol) {
                        case 5:
                            mozoTemporal.setNombre(this.temporal.getNombre());
                            mozoTemporal.setApellido(this.temporal.getApellido());
                            mozoTemporal.setCalle(this.temporal.getCalle());
                            mozoTemporal.setCel(this.temporal.getCel());
                            mozoTemporal.setCiudad(this.temporal.getCiudad());
                            mozoTemporal.setContrasenia(this.contrasenia);
                            mozoTemporal.setDepartamento(this.temporal.getDepartamento());
                            mozoTemporal.setDetalle(this.temporal.getDetalle());
                            mozoTemporal.setEmail(this.temporal.getEmail());
                            mozoTemporal.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            mozoTemporal.setNombreUsuario(this.temporal.getNombreUsuario());
                            mozoTemporal.setNumero(this.temporal.getNumero());
                            mozoTemporal.setRol(this.rol);
                            mozoTemporal.setTelefono(this.temporal.getTelefono());
                            mozoTemporal.setCi(this.convertirCi(this.documento));
                            mozoTemporal.setPuestoTrabajo(this.temporal.getPuestoTrabajo());
                            entidadFacade.crear(this.mozoTemporal);
                            break;
                        case 2:
                            Vehiculo v = vehiculoFacade.buscarPorId(this.vehiculo);
                            choferTemporal.setNombre(this.temporal.getNombre());
                            choferTemporal.setApellido(this.temporal.getApellido());
                            choferTemporal.setCalle(this.temporal.getCalle());
                            choferTemporal.setCel(this.temporal.getCel());
                            choferTemporal.setCiudad(this.temporal.getCiudad());
                            choferTemporal.setContrasenia(this.contrasenia);
                            choferTemporal.setDepartamento(this.temporal.getDepartamento());
                            choferTemporal.setDetalle(this.temporal.getDetalle());
                            choferTemporal.setEmail(this.temporal.getEmail());
                            choferTemporal.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            choferTemporal.setNombreUsuario(this.temporal.getNombreUsuario());
                            choferTemporal.setNumero(this.temporal.getNumero());
                            choferTemporal.setRol(this.rol);
                            choferTemporal.setTelefono(this.temporal.getTelefono());
                            choferTemporal.setCi(this.convertirCi(this.documento));
                            choferTemporal.setVehiculo(v);
                            choferTemporal.setPuestoTrabajo(this.temporal.getPuestoTrabajo());
                            entidadFacade.crear(this.choferTemporal);
                            break;
                        default:
                            this.temporal.setRol(this.rol);
                            this.temporal.setContrasenia(this.contrasenia);
                            this.temporal.setFechaNac(this.convertirDateACalendar(this.fechaNac));
                            this.temporal.setCi(this.convertirCi(this.documento));
                            entidadFacade.crear(this.temporal);
                            break;
                    }
                    setearInfo("Se ha creado " + "exitosamente un nuevo " + mi_param);
                    RequestContext.getCurrentInstance().addCallbackParam("correcto", true);
                    RequestContext.getCurrentInstance().addCallbackParam("param", mi_param);
                    return true;
                } else {
                    super.setearAdvertencia("El Nombre de Usuario ya existe en el Sistema");
                    RequestContext.getCurrentInstance().addCallbackParam("correcto", false);
                    return false;
                }
            } catch (Exception e) {
                setearError(e);
                RequestContext.getCurrentInstance().addCallbackParam("correcto", false);
                RequestContext.getCurrentInstance().addCallbackParam("param", mi_param);
                return false;
            }
        } else {
            return false;
        }
    }

    public enum Accion {

        CREAR, EDITAR, VER;
    }

    private Integer convertirCi(String ci) {
        if (!ci.equals("")) {
            String devolver = ci;
            devolver = devolver.replace(".", "");
            devolver = devolver.replace("-", "");
            return Integer.parseInt(devolver);
        } else {
            return 0;
        }
    }

    public Calendar convertirDateACalendar(Date date) {
        if (date != null) {
            Calendar cal;
            DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
            format.format(date);
            cal = format.getCalendar();
            return cal;
        } else {
            return null;
        }
    }

    private Date convertirCalendarADate(Calendar calendar) {
        if (calendar != null) {
            Date date = calendar.getTime();
            return date;
        } else {
            return null;
        }
    }

    public String imprimirEstado(Boolean estado) {
        if (estado == true) {
            return "Activo";
        } else {
            return "Inactivo";
        }
    }
}
